home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume18 / gnugrep1.3.pch < prev    next >
Encoding:
Internet Message Format  |  1989-03-12  |  48.6 KB

  1. Subject:  v18i019:  GNU Grep 1.2->1.3 patch kit
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: mike@thor.acc.stolaf.edu (Mike Haertel)
  7. Posting-number: Volume 18, Issue 19
  8. Archive-name: gnugrep1.3.pch
  9.  
  10.  
  11. The diffs I sent you earlier today had a small bug in them, they
  12. did not update the version reference in the README.  Enclosed are
  13. the correct diffs, sorry for the inconvenience.
  14.  
  15.     Mike
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then unpack
  19. # it by saving it into a file and typing "sh file".  To overwrite existing
  20. # files, type "sh file -c".  You can also feed this as standard input via
  21. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  22. # will see the following message at the end:
  23. #        "End of shell archive."
  24. # Contents:  cvt1.2to1.3
  25. # Wrapped by rsalz@fig.bbn.com on Mon Mar 13 18:23:34 1989
  26. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  27. if test -f 'cvt1.2to1.3' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'cvt1.2to1.3'\"
  29. else
  30. echo shar: Extracting \"'cvt1.2to1.3'\" \(46818 characters\)
  31. sed "s/^X//" >'cvt1.2to1.3' <<'END_OF_FILE'
  32. Xdiff -rcN grep-1.2/Makefile grep-1.3/Makefile
  33. X*** grep-1.2/Makefile    Thu Oct 13 22:11:28 1988
  34. X--- grep-1.3/Makefile    Tue Feb 28 23:37:13 1989
  35. X***************
  36. X*** 5,27 ****
  37. X  # Add -DUSG for System V.
  38. X  CFLAGS = -O
  39. X  
  40. X  # You may add getopt.o if your C library lacks getopt(); note that
  41. X  # 4.3BSD getopt() is said to be somewhat broken.
  42. X  # Add alloca.o if your machine does not support alloca().
  43. X! OBJS = grep.o dfa.o regex.o
  44. X  
  45. X  all: regress
  46. X  
  47. X! regress: grep
  48. X      cd tests; sh regress.sh
  49. X  
  50. X! grep: $(OBJS)
  51. X!     $(CC) $(CFLAGS) -o grep $(OBJS)
  52. X!     rm -f egrep
  53. X!     ln grep egrep
  54. X  
  55. X  clean:
  56. X!     rm -f grep egrep *.o core tests/core tests/tmp.script
  57. X  
  58. X! dfa.o grep.o: dfa.h
  59. X! grep.o regex.o: regex.h
  60. X--- 5,40 ----
  61. X  # Add -DUSG for System V.
  62. X  CFLAGS = -O
  63. X  
  64. X+ #
  65. X  # You may add getopt.o if your C library lacks getopt(); note that
  66. X  # 4.3BSD getopt() is said to be somewhat broken.
  67. X+ #
  68. X  # Add alloca.o if your machine does not support alloca().
  69. X! #
  70. X! OBJS = dfa.o regex.o
  71. X! GOBJ = grep.o
  72. X! EOBJ = egrep.o
  73. X  
  74. X+ # Space provided for machine dependent libraries.
  75. X+ LIBS =
  76. X+ 
  77. X  all: regress
  78. X  
  79. X! regress: egrep grep
  80. X      cd tests; sh regress.sh
  81. X  
  82. X! egrep: $(OBJS) $(EOBJ)
  83. X!     $(CC) $(CFLAGS) -o egrep $(OBJS) $(EOBJ) $(LIBS)
  84. X! 
  85. X! egrep.o: grep.c
  86. X!     $(CC) $(CFLAGS) -DEGREP -c grep.c
  87. X!     mv grep.o egrep.o
  88. X! 
  89. X! grep: $(OBJS) $(GOBJ)
  90. X!     $(CC) $(CFLAGS) -o grep $(OBJS) $(GOBJ) $(LIBS)
  91. X  
  92. X  clean:
  93. X!     rm -f grep egrep *.o core tests/core tests/tmp.script tests/khadafy.out
  94. X  
  95. X! dfa.o egrep.o grep.o: dfa.h
  96. X! egrep.o grep.o regex.o: regex.h
  97. Xdiff -rcN grep-1.2/README grep-1.3/README
  98. X*** grep-1.2/README    Tue Dec 13 11:04:21 1988
  99. X--- grep-1.3/README    Wed Mar  1 21:43:59 1989
  100. X***************
  101. X*** 1,4 ****
  102. X! This README documents GNU e?grep version 1.2.
  103. X  
  104. X  Changes needed to the makefile under various perversions of Unix are
  105. X  described therein.
  106. X--- 1,4 ----
  107. X! This README documents GNU e?grep version 1.3.
  108. X  
  109. X  Changes needed to the makefile under various perversions of Unix are
  110. X  described therein.
  111. Xdiff -rcN grep-1.2/README.sunos4 grep-1.3/README.sunos4
  112. X*** grep-1.2/README.sunos4    Wed Dec 31 18:00:00 1969
  113. X--- grep-1.3/README.sunos4    Tue Feb 28 22:35:10 1989
  114. X***************
  115. X*** 0 ****
  116. X--- 1,96 ----
  117. X+ Date:    Fri, 24 Feb 89 15:36:40 -0600
  118. X+ To:      mike@wheaties.ai.mit.edu
  119. X+ From:    Dave Cohrs <dave@cs.wisc.edu>
  120. X+ Subject: bug + fix in gnu grep 1.2 (from prep.ai.mit.edu)
  121. X+ 
  122. X+ I tried installing the GNU grep 1.2 on a Sun4 running 4.0.1 and
  123. X+ "Spencer test #36" failed.  After some experimenting, I found and
  124. X+ fixed the bug.  Well, actually, the bug in the the C compiler, but
  125. X+ I managed a workaround.
  126. X+ 
  127. X+ Description:
  128. X+ 
  129. X+ The Sun4 4.0.1 C compiler with -O doesn't generate the correct for
  130. X+ statements of the form
  131. X+     if("string")
  132. X+         x;
  133. X+     else
  134. X+         y;
  135. X+ To be exact, "y;" gets executed, while "x;" should.  This causes the
  136. X+ #define FETCH() to fail for test #36.
  137. X+ 
  138. X+ Fix:
  139. X+ 
  140. X+ In an #ifdef sparc in dfa.c, I made two versions of FETCH, FETCH0() and
  141. X+ the regular FETCH().  The former takes only one argument, the latter
  142. X+ expects its 2nd argument to contain a non-nil string.  This removes
  143. X+ the need to test the constant strings, and the compiler bug isn't
  144. X+ exercised.  I then changed the one instance of FETCH() with a nil
  145. X+ second argument to be FETCH0() instead.
  146. X+ 
  147. X+ dave cohrs
  148. X+ 
  149. X+ ===================================================================
  150. X+ RCS file: RCS/dfa.c,v
  151. X+ retrieving revision 1.1
  152. X+ diff -c -r1.1 dfa.c
  153. X+ *** /tmp/,RCSt1a05930    Fri Feb 24 15:32:33 1989
  154. X+ --- dfa.c    Fri Feb 24 15:23:34 1989
  155. X+ ***************
  156. X+ *** 285,293 ****
  157. X+ --- 285,315 ----
  158. X+                      is turned off). */
  159. X+   
  160. X+   /* Note that characters become unsigned here. */
  161. X+ + #ifdef sparc
  162. X+ + /*
  163. X+ +  * Sun4 4.0.1 C compiler can't compare constant strings correctly.
  164. X+ +  * e.g. if("test") { x; } else { y; }
  165. X+ +  * the compiler will not generate code to execute { x; }, but
  166. X+ +  * executes { y; } instead.
  167. X+ +  */
  168. X+ + #define FETCH0(c)                 \
  169. X+ +   {                         \
  170. X+ +     if (! lexleft)                 \
  171. X+ +       return _END;                 \
  172. X+ +     (c) = (unsigned char) *lexptr++;  \
  173. X+ +     --lexleft;                     \
  174. X+ +   }
  175. X+   #define FETCH(c, eoferr)             \
  176. X+     {                         \
  177. X+       if (! lexleft)                 \
  178. X+ +       regerror(eoferr);            \
  179. X+ +     (c) = (unsigned char) *lexptr++;  \
  180. X+ +     --lexleft;                     \
  181. X+ +   }
  182. X+ + #else
  183. X+ + #define FETCH(c, eoferr)             \
  184. X+ +   {                         \
  185. X+ +     if (! lexleft)                 \
  186. X+         if (eoferr)                 \
  187. X+       regerror(eoferr);            \
  188. X+         else                     \
  189. X+ ***************
  190. X+ *** 295,300 ****
  191. X+ --- 317,323 ----
  192. X+       (c) = (unsigned char) *lexptr++;  \
  193. X+       --lexleft;                     \
  194. X+     }
  195. X+ + #endif sparc
  196. X+   
  197. X+   static _token
  198. X+   lex()
  199. X+ ***************
  200. X+ *** 303,309 ****
  201. X+ --- 326,336 ----
  202. X+     int invert;
  203. X+     _charset cset;
  204. X+   
  205. X+ + #ifdef sparc
  206. X+ +   FETCH0(c);
  207. X+ + #else
  208. X+     FETCH(c, (char *) 0);
  209. X+ + #endif sparc
  210. X+     switch (c)
  211. X+       {
  212. X+       case '^':
  213. Xdiff -rcN grep-1.2/dfa.c grep-1.3/dfa.c
  214. X*** grep-1.2/dfa.c    Thu Oct 13 22:11:29 1988
  215. X--- grep-1.3/dfa.c    Tue Feb 28 18:46:35 1989
  216. X***************
  217. X*** 105,110 ****
  218. X--- 105,112 ----
  219. X  You are forbidden to forbid anyone else to use, share and improve
  220. X  what you give them.   Help stamp out software-hoarding!  */
  221. X  
  222. X+ #include <stdio.h>
  223. X+ #include <assert.h>
  224. X  #include <ctype.h>
  225. X  #include "dfa.h"
  226. X  
  227. X***************
  228. X*** 135,140 ****
  229. X--- 137,143 ----
  230. X  {
  231. X    ptr_t r = malloc(n);
  232. X  
  233. X+   assert(n != 0);
  234. X    if (r)
  235. X      return r;
  236. X    else
  237. X***************
  238. X*** 148,153 ****
  239. X--- 151,157 ----
  240. X  {
  241. X    ptr_t r = realloc(p, n);
  242. X  
  243. X+   assert(n != 0);
  244. X    if (r)
  245. X      return r;
  246. X    else
  247. X***************
  248. X*** 1122,1128 ****
  249. X        {
  250. X      copy(&r->follows[i], &merged);
  251. X      epsclosure(&merged, r);
  252. X!     REALLOC(r->follows[i].elems, _position, merged.nelem);
  253. X      copy(&merged, &r->follows[i]);
  254. X        }
  255. X  
  256. X--- 1126,1133 ----
  257. X        {
  258. X      copy(&r->follows[i], &merged);
  259. X      epsclosure(&merged, r);
  260. X!     if (r->follows[i].nelem < merged.nelem)
  261. X!       REALLOC(r->follows[i].elems, _position, merged.nelem);
  262. X      copy(&merged, &r->follows[i]);
  263. X        }
  264. X  
  265. X***************
  266. X*** 1719,1742 ****
  267. X  Having found the postfix representation of the regular expression,
  268. X  try to find a long sequence of characters that must appear in any line
  269. X  containing the r.e.
  270. X! Finding a "longest" sequence is beyond the scope of this bagatelle;
  271. X! we take the easy way out and hope for the best.
  272. X  
  273. X! We do a bottom-up calculation of several (possibly zero-length) sequences
  274. X! of characters that must appear in matches of r.e.'s represented by trees
  275. X! rooted at the nodes of the postfix representation:
  276. X      sequences that must appear at the left of the match ("left")
  277. X      sequences that must appear at the right of the match ("right")
  278. X!     sequences that must appear somewhere in the match ("in")
  279. X      sequences that must constitute the match ("is")
  280. X! When we get to the root of the tree, we use its calculated "in" sequence
  281. X! as our answer.  The sequence we find is returned in r->must (where "r" is
  282. X! the single argument passed to "regmust"); the length of the sequence is
  283. X! returned in r->mustn.
  284. X  
  285. X  The sequences calculated for the various types of node (in pseudo ANSI c)
  286. X  are shown below.  "p" is the operand of unary operators (and the left-hand
  287. X! operand of binary operators); "q" is the right-hand operand of binary operators.
  288. X  "ZERO" means "a zero-length sequence" below.
  289. X  
  290. X  Type    left        right        is        in
  291. X--- 1724,1749 ----
  292. X  Having found the postfix representation of the regular expression,
  293. X  try to find a long sequence of characters that must appear in any line
  294. X  containing the r.e.
  295. X! Finding a "longest" sequence is beyond the scope here;
  296. X! we take an easy way out and hope for the best.
  297. X! (Take "(ab|a)b"--please.)
  298. X  
  299. X! We do a bottom-up calculation of sequences of characters that must appear
  300. X! in matches of r.e.'s represented by trees rooted at the nodes of the postfix
  301. X! representation:
  302. X      sequences that must appear at the left of the match ("left")
  303. X      sequences that must appear at the right of the match ("right")
  304. X!     lists of sequences that must appear somewhere in the match ("in")
  305. X      sequences that must constitute the match ("is")
  306. X! When we get to the root of the tree, we use one of the longest of its
  307. X! calculated "in" sequences as our answer.  The sequence we find is returned in
  308. X! r->must (where "r" is the single argument passed to "regmust");
  309. X! the length of the sequence is returned in r->mustn.
  310. X  
  311. X  The sequences calculated for the various types of node (in pseudo ANSI c)
  312. X  are shown below.  "p" is the operand of unary operators (and the left-hand
  313. X! operand of binary operators); "q" is the right-hand operand of binary operators
  314. X! .
  315. X  "ZERO" means "a zero-length sequence" below.
  316. X  
  317. X  Type    left        right        is        in
  318. X***************
  319. X*** 1749,1865 ****
  320. X  
  321. X  QMARK    ZERO        ZERO        ZERO        ZERO
  322. X  
  323. X! PLUS    p->left        p->right    ZERO        ZERO
  324. X  
  325. X! CAT    (p->is==ZERO)?    (q->is==ZERO)?    (p->is!=ZERO &&    longest of
  326. X!     p->left :    q->right :    q->is!=ZERO) ?    p->in, q->in, or
  327. X      p->is##q->left    p->right##q->is    p->is##q->is :    p->right##q->left
  328. X                      ZERO
  329. X  
  330. X! OR    longest common    longest common    (do p->is and    (do p->in and
  331. X!     leading        trailing    q->is have same    q->in have same
  332. X!     (sub)sequence    (sub)sequence    length and    length and
  333. X!     of p->left    of p->right    content) ?    content) ?
  334. X!     and q->left    and q->right    p->is : NULL    p->in : NULL
  335. X  
  336. X  If there's anything else we recognize in the tree, all four sequences get set
  337. X  to zero-length sequences.  If there's something we don't recognize in the tree,
  338. X  we just return a zero-length sequence.
  339. X  
  340. X! After the above calculations are performed, three additional steps are taken:
  341. X  
  342. X! 1.    If there's a non-zero-length "is" sequence, it replaces the
  343. X!     "left", "right", and "in" sequences.
  344. X! 2.    If the "left" sequence is longer than the "in" sequence, it replaces
  345. X!     the "in" sequence.
  346. X! 3.    If the "right" sequence is longer than the "in" sequence, it replaces
  347. X!     the "in" sequence.
  348. X! 
  349. X! Possibilities:
  350. X! 1.    Find the longest common (sub)sequence of p->in and q->in when doing
  351. X!     an OR node's "in" sequence?  Possibly effective, as in
  352. X!         egrep 'pepsi|epsilon'
  353. X!     but is it cheap and easy enough?
  354. X! 2.    In replacing "in" sequences with "left" and "right" sequences, how
  355. X!     should ties be broken?
  356. X! 3.    Switch to allocated memory, rather than relying on a defined MUST_MAX?
  357. X  */
  358. X  
  359. X! #define TRUE    1
  360. X! #define FALSE    0
  361. X  
  362. X! typedef struct {
  363. X!     int    n;
  364. X!     char    p[MUST_MAX];
  365. X! } counted;
  366. X  
  367. X! #define initcounted(cp)    ((cp)->n = 0)
  368. X! 
  369. X! static void
  370. X! cntcpy(top, fromp)
  371. X! counted *    top;
  372. X! counted *    fromp;
  373. X! {
  374. X!     register char *    fp;
  375. X!     register char *    tp;
  376. X!     register int    n;
  377. X! 
  378. X!     fp = fromp->p;
  379. X!     tp = top->p;
  380. X!     n = fromp->n;
  381. X!     top->n = n;
  382. X!     while (n-- > 0)
  383. X!         *tp++ = *fp++;
  384. X! }
  385. X! 
  386. X! static void
  387. X! cntcat(top, fromp)
  388. X! counted *    top;
  389. X! counted *    fromp;
  390. X! {
  391. X!     register char *    fp;
  392. X!     register char *    tp;
  393. X!     register int    n;
  394. X! 
  395. X!     fp = fromp->p;
  396. X!     tp = top->p + top->n;
  397. X!     n = fromp->n;
  398. X!     top->n += n;
  399. X!     while (n-- > 0)
  400. X!         *tp++ = *fp++;
  401. X! }
  402. X! 
  403. X! static int
  404. X! cntsame(acp, bcp)
  405. X! counted *    acp;
  406. X! counted *    bcp;
  407. X  {
  408. X      register int    i;
  409. X  
  410. X!     if (acp->n != bcp->n)
  411. X!         return FALSE;
  412. X!     for (i = 0; i < acp->n; ++i)
  413. X!         if (acp->p[i] != bcp->p[i])
  414. X!             return FALSE;
  415. X!     return TRUE;
  416. X  }
  417. X  
  418. X  
  419. X  typedef struct {
  420. X!     counted    left;
  421. X!     counted    right;
  422. X!     counted    in;
  423. X!     counted    is;
  424. X  } must;
  425. X  
  426. X  static void
  427. X! initmust(mp)
  428. X! must *    mp;
  429. X  {
  430. X!     initcounted(&mp->left);
  431. X!     initcounted(&mp->right);
  432. X!     initcounted(&mp->in);
  433. X!     initcounted(&mp->is);
  434. X  }
  435. X  
  436. X  static void
  437. X--- 1756,2022 ----
  438. X  
  439. X  QMARK    ZERO        ZERO        ZERO        ZERO
  440. X  
  441. X! PLUS    p->left        p->right    ZERO        p->in
  442. X  
  443. X! CAT    (p->is==ZERO)?    (q->is==ZERO)?    (p->is!=ZERO &&    p->in plus
  444. X!     p->left :    q->right :    q->is!=ZERO) ?    q->in plus
  445. X      p->is##q->left    p->right##q->is    p->is##q->is :    p->right##q->left
  446. X                      ZERO
  447. X  
  448. X! OR    longest common    longest common    (do p->is and    substrings common to
  449. X!     leading        trailing    q->is have same    p->in and q->in
  450. X!     (sub)sequence    (sub)sequence    length and    
  451. X!     of p->left    of p->right    content) ?    
  452. X!     and q->left    and q->right    p->is : NULL    
  453. X  
  454. X  If there's anything else we recognize in the tree, all four sequences get set
  455. X  to zero-length sequences.  If there's something we don't recognize in the tree,
  456. X  we just return a zero-length sequence.
  457. X  
  458. X! Break ties in favor of infrequent letters (choosing 'zzz' in preference to
  459. X! 'aaa')?
  460. X  
  461. X! And. . .is it here or someplace that we might ponder "optimizations" such as
  462. X!     egrep 'psi|epsilon'    ->    egrep 'psi'
  463. X!     egrep 'pepsi|epsilon'    ->    egrep 'epsi'
  464. X!                     (Yes, we now find "epsi" as a "string
  465. X!                     that must occur", but we might also
  466. X!                     simplify the *entire* r.e. being sought
  467. X! )
  468. X!     grep '[c]'        ->    grep 'c'
  469. X!     grep '(ab|a)b'        ->    grep 'ab'
  470. X!     grep 'ab*'        ->    grep 'a'
  471. X!     grep 'a*b'        ->    grep 'b'
  472. X! There are several issues:
  473. X!     Is optimization easy (enough)?
  474. X! 
  475. X!     Does optimization actually accomplish anything,
  476. X!     or is the automaton you get from "psi|epsilon" (for example)
  477. X!     the same as the one you get from "psi" (for example)?
  478. X! 
  479. X!     Are optimizable r.e.'s likely to be used in real-life situations
  480. X!     (something like 'ab*' is probably unlikely; something like is
  481. X!     'psi|epsilon' is likelier)?
  482. X  */
  483. X  
  484. X! static char *
  485. X! icatalloc(old, new)
  486. X! char *    old;
  487. X! char *    new;
  488. X! {
  489. X!     register char *    result;
  490. X!     register int    oldsize, newsize;
  491. X! 
  492. X!     newsize = (new == NULL) ? 0 : strlen(new);
  493. X!     if (old == NULL)
  494. X!         oldsize = 0;
  495. X!     else if (newsize == 0)
  496. X!         return old;
  497. X!     else    oldsize = strlen(old);
  498. X!     if (old == NULL)
  499. X!         result = (char *) malloc(newsize + 1);
  500. X!     else    result = (char *) realloc((void *) old, oldsize + newsize + 1);
  501. X!     if (result != NULL && new != NULL)
  502. X!         (void) strcpy(result + oldsize, new);
  503. X!     return result;
  504. X! }
  505. X! 
  506. X! static char *
  507. X! icpyalloc(string)
  508. X! const char *    string;
  509. X! {
  510. X!     return icatalloc((char *) NULL, string);
  511. X! }
  512. X! 
  513. X! static char *
  514. X! istrstr(lookin, lookfor)
  515. X! char *        lookin;
  516. X! register char *    lookfor;
  517. X! {
  518. X!     register char *    cp;
  519. X!     register int    len;
  520. X  
  521. X!     len = strlen(lookfor);
  522. X!     for (cp = lookin; *cp != '\0'; ++cp)
  523. X!         if (strncmp(cp, lookfor, len) == 0)
  524. X!             return cp;
  525. X!     return NULL;
  526. X! }
  527. X! 
  528. X! static void
  529. X! ifree(cp)
  530. X! char *    cp;
  531. X! {
  532. X!     if (cp != NULL)
  533. X!         free(cp);
  534. X! }
  535. X! 
  536. X! static void
  537. X! freelist(cpp)
  538. X! register char **    cpp;
  539. X! {
  540. X!     register int    i;
  541. X! 
  542. X!     if (cpp == NULL)
  543. X!         return;
  544. X!     for (i = 0; cpp[i] != NULL; ++i) {
  545. X!         free(cpp[i]);
  546. X!         cpp[i] = NULL;
  547. X!     }
  548. X! }
  549. X! 
  550. X! static char **
  551. X! enlist(cpp, new, len)
  552. X! register char **    cpp;
  553. X! register char *        new;
  554. X! {
  555. X!     register int    i, j;
  556. X! 
  557. X!     if (cpp == NULL)
  558. X!         return NULL;
  559. X!     if ((new = icpyalloc(new)) == NULL) {
  560. X!         freelist(cpp);
  561. X!         return NULL;
  562. X!     }
  563. X!     new[len] = '\0';
  564. X!     /*
  565. X!     ** Is there already something in the list that's new (or longer)?
  566. X!     */
  567. X!     for (i = 0; cpp[i] != NULL; ++i)
  568. X!         if (istrstr(cpp[i], new) != NULL) {
  569. X!             free(new);
  570. X!             return cpp;
  571. X!         }
  572. X!     /*
  573. X!     ** Eliminate any obsoleted strings.
  574. X!     */
  575. X!     j = 0;
  576. X!     while (cpp[j] != NULL)
  577. X!         if (istrstr(new, cpp[j]) == NULL)
  578. X!             ++j;
  579. X!         else {
  580. X!             free(cpp[j]);
  581. X!             if (--i == j)
  582. X!                 break;
  583. X!             cpp[j] = cpp[i];
  584. X!         }
  585. X!     /*
  586. X!     ** Add the new string.
  587. X!     */
  588. X!     cpp = (char **) realloc((char *) cpp, (i + 2) * sizeof *cpp);
  589. X!     if (cpp == NULL)
  590. X!         return NULL;
  591. X!     cpp[i] = new;
  592. X!     cpp[i + 1] = NULL;
  593. X!     return cpp;
  594. X! }
  595. X! 
  596. X! /*
  597. X! ** Given pointers to two strings,
  598. X! ** return a pointer to an allocated list of their distinct common substrings.
  599. X! ** Return NULL if something seems wild.
  600. X! */
  601. X  
  602. X! static char **
  603. X! comsubs(left, right)
  604. X! char *    left;
  605. X! char *    right;
  606. X! {
  607. X!     register char **    cpp;
  608. X!     register char *        lcp;
  609. X!     register char *        rcp;
  610. X!     register int        i, len;
  611. X! 
  612. X!     if (left == NULL || right == NULL)
  613. X!         return NULL;
  614. X!     cpp = (char **) malloc(sizeof *cpp);
  615. X!     if (cpp == NULL)
  616. X!         return NULL;
  617. X!     cpp[0] = NULL;
  618. X!     for (lcp = left; *lcp != '\0'; ++lcp) {
  619. X!         len = 0;
  620. X!         rcp = strchr(right, *lcp);
  621. X!         while (rcp != NULL) {
  622. X!             for (i = 1; lcp[i] != '\0' && lcp[i] == rcp[i]; ++i)
  623. X!                 ;
  624. X!             if (i > len)
  625. X!                 len = i;
  626. X!             rcp = strchr(rcp + 1, *lcp);
  627. X!         }
  628. X!         if (len == 0)
  629. X!             continue;
  630. X!         if ((cpp = enlist(cpp, lcp, len)) == NULL)
  631. X!             break;
  632. X!     }
  633. X!     return cpp;
  634. X! }
  635. X! 
  636. X! static char **
  637. X! addlists(old, new)
  638. X! char **    old;
  639. X! char **    new;
  640. X  {
  641. X      register int    i;
  642. X  
  643. X!     if (old == NULL || new == NULL)
  644. X!         return NULL;
  645. X!     for (i = 0; new[i] != NULL; ++i) {
  646. X!         old = enlist(old, new[i], strlen(new[i]));
  647. X!         if (old == NULL)
  648. X!             break;
  649. X!     }
  650. X!     return old;
  651. X  }
  652. X  
  653. X+ /*
  654. X+ ** Given two lists of substrings,
  655. X+ ** return a new list giving substrings common to both.
  656. X+ */
  657. X+ 
  658. X+ static char **
  659. X+ inboth(left, right)
  660. X+ char **    left;
  661. X+ char **    right;
  662. X+ {
  663. X+     register char **    both;
  664. X+     register char **    temp;
  665. X+     register int        lnum, rnum;
  666. X+ 
  667. X+     if (left == NULL || right == NULL)
  668. X+         return NULL;
  669. X+     both = (char **) malloc(sizeof *both);
  670. X+     if (both == NULL)
  671. X+         return NULL;
  672. X+     both[0] = NULL;
  673. X+     for (lnum = 0; left[lnum] != NULL; ++lnum) {
  674. X+         for (rnum = 0; right[rnum] != NULL; ++rnum) {
  675. X+             temp = comsubs(left[lnum], right[rnum]);
  676. X+             if (temp == NULL) {
  677. X+                 freelist(both);
  678. X+                 return NULL;
  679. X+             }
  680. X+             both = addlists(both, temp);
  681. X+             freelist(temp);
  682. X+             if (both == NULL)
  683. X+                 return NULL;
  684. X+         }
  685. X+     }
  686. X+     return both;
  687. X+ }
  688. X  
  689. X  typedef struct {
  690. X!     char **    in;
  691. X!     char *    left;
  692. X!     char *    right;
  693. X!     char *    is;
  694. X  } must;
  695. X  
  696. X  static void
  697. X! resetmust(mp)
  698. X! register must *    mp;
  699. X  {
  700. X!     mp->left[0] = mp->right[0] = mp->is[0] = '\0';
  701. X!     freelist(mp->in);
  702. X  }
  703. X  
  704. X  static void
  705. X***************
  706. X*** 1866,1884 ****
  707. X  regmust(r)
  708. X  register struct regexp *    r;
  709. X  {
  710. X!     must            musts[MUST_MAX];
  711. X      register must *        mp;
  712. X!     counted            result;
  713. X      register int        ri;
  714. X      register int        i;
  715. X      register _token        t;
  716. X  
  717. X      reg->mustn = 0;
  718. X      reg->must[0] = '\0';
  719. X!     if (reg->tindex > MUST_MAX)
  720. X          return;
  721. X      mp = musts;
  722. X!     initcounted(&result);
  723. X      for (ri = 0; ri < reg->tindex; ++ri) {
  724. X          switch (t = reg->tokens[ri]) {
  725. X          case _ALLBEGLINE:
  726. X--- 2023,2056 ----
  727. X  regmust(r)
  728. X  register struct regexp *    r;
  729. X  {
  730. X!     register must *        musts;
  731. X      register must *        mp;
  732. X!     register char *        result;
  733. X      register int        ri;
  734. X      register int        i;
  735. X      register _token        t;
  736. X+     static must        must0;
  737. X  
  738. X      reg->mustn = 0;
  739. X      reg->must[0] = '\0';
  740. X!     musts = (must *) malloc((reg->tindex + 1) * sizeof *musts);
  741. X!     if (musts == NULL)
  742. X          return;
  743. X      mp = musts;
  744. X!     for (i = 0; i <= reg->tindex; ++i)
  745. X!         mp[i] = must0;
  746. X!     for (i = 0; i <= reg->tindex; ++i) {
  747. X!         mp[i].in = (char **) malloc(sizeof *mp[i].in);
  748. X!         mp[i].left = malloc(2);
  749. X!         mp[i].right = malloc(2);
  750. X!         mp[i].is = malloc(2);
  751. X!         if (mp[i].in == NULL || mp[i].left == NULL ||
  752. X!             mp[i].right == NULL || mp[i].is == NULL)
  753. X!                 goto done;
  754. X!         mp[i].left[0] = mp[i].right[0] = mp[i].is[0] = '\0';
  755. X!         mp[i].in[0] = NULL;
  756. X!     }
  757. X!     result = "";
  758. X      for (ri = 0; ri < reg->tindex; ++ri) {
  759. X          switch (t = reg->tokens[ri]) {
  760. X          case _ALLBEGLINE:
  761. X***************
  762. X*** 1894,1900 ****
  763. X          case _LIMWORD:
  764. X          case _NOTLIMWORD:
  765. X          case _BACKREF:
  766. X!             initmust(mp);
  767. X              break;
  768. X          case _STAR:
  769. X          case _QMARK:
  770. X--- 2066,2072 ----
  771. X          case _LIMWORD:
  772. X          case _NOTLIMWORD:
  773. X          case _BACKREF:
  774. X!             resetmust(mp);
  775. X              break;
  776. X          case _STAR:
  777. X          case _QMARK:
  778. X***************
  779. X*** 1901,1945 ****
  780. X              if (mp <= musts)
  781. X                  goto done;    /* "cannot happen" */
  782. X              --mp;
  783. X!             initmust(mp);
  784. X              break;
  785. X          case _OR:
  786. X              if (mp < &musts[2])
  787. X                  goto done;    /* "cannot happen" */
  788. X              {
  789. X!                 register must *    lmp;
  790. X!                 register must *    rmp;
  791. X!                 register int    j, n;
  792. X  
  793. X                  rmp = --mp;
  794. X                  lmp = --mp;
  795. X                  /* Guaranteed to be.  Unlikely, but. . . */
  796. X!                 if (!cntsame(&lmp->is, &rmp->is))
  797. X!                     initcounted(&lmp->is);
  798. X                  /* Left side--easy */
  799. X!                 n = lmp->left.n;
  800. X!                 if (n > rmp->left.n)
  801. X!                     n = rmp->left.n;
  802. X!                 for (i = 0; i < n; ++i)
  803. X!                     if (lmp->left.p[i] != rmp->left.p[i])
  804. X!                         break;
  805. X!                 lmp->left.n = i;
  806. X                  /* Right side */
  807. X!                 n = lmp->right.n;
  808. X!                 if (n > rmp->right.n)
  809. X!                     n = rmp->right.n;
  810. X                  for (i = 0; i < n; ++i)
  811. X!                     if (lmp->right.p[lmp->right.n-i-1] !=
  812. X!                         rmp->right.p[rmp->right.n-i-1])
  813. X                          break;
  814. X                  for (j = 0; j < i; ++j)
  815. X!                     lmp->right.p[j] =
  816. X!                         lmp->right.p[(lmp->right.n -
  817. X!                             i) + j];
  818. X!                 lmp->right.n = i;
  819. X!                 /* Includes.  Unlikely, but. . . */
  820. X!                 if (!cntsame(&lmp->in, &rmp->in))
  821. X!                     initcounted(&lmp->in);
  822. X              }
  823. X              break;
  824. X          case _PLUS:
  825. X--- 2073,2120 ----
  826. X              if (mp <= musts)
  827. X                  goto done;    /* "cannot happen" */
  828. X              --mp;
  829. X!             resetmust(mp);
  830. X              break;
  831. X          case _OR:
  832. X              if (mp < &musts[2])
  833. X                  goto done;    /* "cannot happen" */
  834. X              {
  835. X!                 register char **    new;
  836. X!                 register must *        lmp;
  837. X!                 register must *        rmp;
  838. X!                 register int        j, ln, rn, n;
  839. X  
  840. X                  rmp = --mp;
  841. X                  lmp = --mp;
  842. X                  /* Guaranteed to be.  Unlikely, but. . . */
  843. X!                 if (strcmp(lmp->is, rmp->is) != 0)
  844. X!                     lmp->is[0] = '\0';
  845. X                  /* Left side--easy */
  846. X!                 i = 0;
  847. X!                 while (lmp->left[i] != '\0' &&
  848. X!                     lmp->left[i] == rmp->left[i])
  849. X!                         ++i;
  850. X!                 lmp->left[i] = '\0';
  851. X                  /* Right side */
  852. X!                 ln = strlen(lmp->right);
  853. X!                 rn = strlen(rmp->right);
  854. X!                 n = ln;
  855. X!                 if (n > rn)
  856. X!                     n = rn;
  857. X                  for (i = 0; i < n; ++i)
  858. X!                     if (lmp->right[ln - i - 1] !=
  859. X!                         rmp->right[rn - i - 1])
  860. X                          break;
  861. X                  for (j = 0; j < i; ++j)
  862. X!                     lmp->right[j] =
  863. X!                         lmp->right[(ln - i) + j];
  864. X!                 lmp->right[j] = '\0';
  865. X!                 new = inboth(lmp->in, rmp->in);
  866. X!                 if (new == NULL)
  867. X!                     goto done;
  868. X!                 freelist(lmp->in);
  869. X!                 free((char *) lmp->in);
  870. X!                 lmp->in = new;
  871. X              }
  872. X              break;
  873. X          case _PLUS:
  874. X***************
  875. X*** 1946,2001 ****
  876. X              if (mp <= musts)
  877. X                  goto done;    /* "cannot happen" */
  878. X              --mp;
  879. X!             initcounted(&mp->is);
  880. X              break;
  881. X          case _END:
  882. X              if (mp != &musts[1])
  883. X                  goto done;    /* "cannot happen" */
  884. X!             result = musts[0].in;
  885. X              goto done;
  886. X          case _CAT:
  887. X              if (mp < &musts[2])
  888. X                  goto done;    /* "cannot happen" */
  889. X              {
  890. X!                 must *    lmp;
  891. X!                 must *    rmp;
  892. X!                 must    new;
  893. X!                 must *    nmp;
  894. X!                 int    a, b, c;
  895. X  
  896. X                  rmp = --mp;
  897. X                  lmp = --mp;
  898. X!                 nmp = &new;
  899. X!                 initmust(nmp);
  900. X                  /* Left-hand */
  901. X!                 cntcat(&nmp->left, &lmp->left);
  902. X!                 if (lmp->is.n != 0)
  903. X!                     cntcat(&nmp->left, &rmp->left);
  904. X                  /* Right-hand */
  905. X!                 if (rmp->is.n != 0)
  906. X!                     cntcat(&nmp->right, &lmp->right);
  907. X!                 cntcat(&nmp->right, &rmp->right);
  908. X                  /* Guaranteed to be */
  909. X!                 if (lmp->is.n != 0 && rmp->is.n != 0) {
  910. X!                     cntcat(&nmp->is, &lmp->is);
  911. X!                     cntcat(&nmp->is, &rmp->is);
  912. X                  }
  913. X-                 /* Interior */
  914. X-                 a = lmp->in.n;
  915. X-                 b = rmp->in.n;
  916. X-                 c = lmp->right.n + rmp->left.n;
  917. X-                 if (a == 0 && b == 0 && c == 0) {
  918. X-                     /* nothing */
  919. X-                     ;
  920. X-                 } else if (c > a && c > b) {
  921. X-                     cntcat(&nmp->in, &lmp->right);
  922. X-                     cntcat(&nmp->in, &rmp->left);
  923. X-                 } else if (a > b) {
  924. X-                     cntcat(&nmp->in, &lmp->in);
  925. X-                 } else {
  926. X-                     cntcat(&nmp->in, &rmp->in);
  927. X-                 }
  928. X-                 *mp = new;
  929. X              }
  930. X              break;
  931. X          default:
  932. X--- 2121,2187 ----
  933. X              if (mp <= musts)
  934. X                  goto done;    /* "cannot happen" */
  935. X              --mp;
  936. X!             mp->is[0] = '\0';
  937. X              break;
  938. X          case _END:
  939. X              if (mp != &musts[1])
  940. X                  goto done;    /* "cannot happen" */
  941. X!             for (i = 0; musts[0].in[i] != NULL; ++i)
  942. X!                 if (strlen(musts[0].in[i]) > strlen(result))
  943. X!                     result = musts[0].in[i];
  944. X              goto done;
  945. X          case _CAT:
  946. X              if (mp < &musts[2])
  947. X                  goto done;    /* "cannot happen" */
  948. X              {
  949. X!                 register must *    lmp;
  950. X!                 register must *    rmp;
  951. X  
  952. X                  rmp = --mp;
  953. X                  lmp = --mp;
  954. X!                 /*
  955. X!                 ** In.  Everything in left, plus everything in
  956. X!                 ** right, plus catenation of
  957. X!                 ** left's right and right's left.
  958. X!                 */
  959. X!                 lmp->in = addlists(lmp->in, rmp->in);
  960. X!                 if (lmp->in == NULL)
  961. X!                     goto done;
  962. X!                 if (lmp->right[0] != '\0' &&
  963. X!                     rmp->left[0] != '\0') {
  964. X!                         register char *    tp;
  965. X! 
  966. X!                         tp = icpyalloc(lmp->right);
  967. X!                         if (tp == NULL)
  968. X!                             goto done;
  969. X!                         tp = icatalloc(tp, rmp->left);
  970. X!                         if (tp == NULL)
  971. X!                             goto done;
  972. X!                         lmp->in = enlist(lmp->in, tp,
  973. X!                             strlen(tp));
  974. X!                         free(tp);
  975. X!                         if (lmp->in == NULL)
  976. X!                             goto done;
  977. X!                 }
  978. X                  /* Left-hand */
  979. X!                 if (lmp->is[0] != '\0') {
  980. X!                     lmp->left = icatalloc(lmp->left,
  981. X!                         rmp->left);
  982. X!                     if (lmp->left == NULL)
  983. X!                         goto done;
  984. X!                 }
  985. X                  /* Right-hand */
  986. X!                 if (rmp->is[0] == '\0')
  987. X!                     lmp->right[0] = '\0';
  988. X!                 lmp->right = icatalloc(lmp->right, rmp->right);
  989. X!                 if (lmp->right == NULL)
  990. X!                     goto done;
  991. X                  /* Guaranteed to be */
  992. X!                 if (lmp->is[0] != '\0' && rmp->is[0] != '\0') {
  993. X!                     lmp->is = icatalloc(lmp->is, rmp->is);
  994. X!                     if (lmp->is == NULL)
  995. X!                         goto done;
  996. X                  }
  997. X              }
  998. X              break;
  999. X          default:
  1000. X***************
  1001. X*** 2002,2036 ****
  1002. X              if (t < _END) {
  1003. X                  /* "cannot happen" */
  1004. X                  goto done;
  1005. X              } else if (t >= _SET) {
  1006. X                  /* easy enough */
  1007. X!                 initmust(mp);
  1008. X              } else {
  1009. X                  /* plain character */
  1010. X!                 mp->left.p[0] = mp->right.p[0] =
  1011. X!                     mp->in.p[0] = mp->is.p[0] = t;
  1012. X!                 mp->left.n = mp->right.n =
  1013. X!                     mp->in.n = mp->is.n = 1;
  1014. X!                 break;
  1015. X              }
  1016. X              break;
  1017. X          }
  1018. X-         /*
  1019. X-         ** "Additional steps"
  1020. X-         */
  1021. X-         if (mp->is.n > 0) {
  1022. X-             cntcpy(&mp->left, &mp->is);
  1023. X-             cntcpy(&mp->right, &mp->is);
  1024. X-             cntcpy(&mp->in, &mp->is);
  1025. X-         }
  1026. X-         if (mp->left.n > mp->in.n)
  1027. X-             cntcpy(&mp->in, &mp->left);
  1028. X-         if (mp->right.n > mp->in.n)
  1029. X-             cntcpy(&mp->in, &mp->right);
  1030. X          ++mp;
  1031. X      }
  1032. X  done:
  1033. X!     reg->mustn = result.n;
  1034. X!     for (i = 0; i < result.n; ++i)
  1035. X!         reg->must[i] = result.p[i];
  1036. X  }
  1037. X--- 2188,2223 ----
  1038. X              if (t < _END) {
  1039. X                  /* "cannot happen" */
  1040. X                  goto done;
  1041. X+             } else if (t == '\0') {
  1042. X+                 /* not on *my* shift */
  1043. X+                 goto done;
  1044. X              } else if (t >= _SET) {
  1045. X                  /* easy enough */
  1046. X!                 resetmust(mp);
  1047. X              } else {
  1048. X                  /* plain character */
  1049. X!                 resetmust(mp);
  1050. X!                 mp->is[0] = mp->left[0] = mp->right[0] = t;
  1051. X!                 mp->is[1] = mp->left[1] = mp->right[1] = '\0';
  1052. X!                 mp->in = enlist(mp->in, mp->is, 1);
  1053. X!                 if (mp->in == NULL)
  1054. X!                     goto done;
  1055. X              }
  1056. X              break;
  1057. X          }
  1058. X          ++mp;
  1059. X      }
  1060. X  done:
  1061. X!     (void) strncpy(reg->must, result, MUST_MAX - 1);
  1062. X!     reg->must[MUST_MAX - 1] = '\0';
  1063. X!     reg->mustn = strlen(reg->must);
  1064. X!     mp = musts;
  1065. X!     for (i = 0; i <= reg->tindex; ++i) {
  1066. X!         freelist(mp[i].in);
  1067. X!         ifree((char *) mp[i].in);
  1068. X!         ifree(mp[i].left);
  1069. X!         ifree(mp[i].right);
  1070. X!         ifree(mp[i].is);
  1071. X!     }
  1072. X!     free((char *) mp);
  1073. X  }
  1074. Xdiff -rcN grep-1.2/dfa.h grep-1.3/dfa.h
  1075. X*** grep-1.2/dfa.h    Thu Oct 13 22:11:29 1988
  1076. X--- grep-1.3/dfa.h    Tue Feb 28 21:53:15 1989
  1077. X***************
  1078. X*** 103,108 ****
  1079. X--- 103,117 ----
  1080. X  You are forbidden to forbid anyone else to use, share and improve
  1081. X  what you give them.   Help stamp out software-hoarding!  */
  1082. X  
  1083. X+ 
  1084. X+ #ifdef USG
  1085. X+ #include <string.h>
  1086. X+ extern char *index();
  1087. X+ #else
  1088. X+ #include <strings.h>
  1089. X+ extern char *strchr(), *strrchr(), *memcpy();
  1090. X+ #endif
  1091. X+ 
  1092. X  #ifdef __STDC__
  1093. X  
  1094. X  /* Missing include files for GNU C. */
  1095. X***************
  1096. X*** 113,124 ****
  1097. X  extern void *realloc(void *, size_t);
  1098. X  extern void free(void *);
  1099. X  
  1100. X- #ifndef USG
  1101. X- extern char *strchr(), *strrchr(), *memcpy();
  1102. X- #else
  1103. X- extern char *index();
  1104. X- #endif
  1105. X- 
  1106. X  extern char *bcopy(), *bzero();
  1107. X  
  1108. X  #ifdef SOMEDAY
  1109. X--- 122,127 ----
  1110. X***************
  1111. X*** 136,147 ****
  1112. X  extern char *calloc(), *malloc(), *realloc();
  1113. X  extern void free();
  1114. X  
  1115. X- #ifndef USG
  1116. X- extern char *strchr(), *strrchr(), *memcpy();
  1117. X- #else
  1118. X- extern char *index();
  1119. X- #endif
  1120. X- 
  1121. X  extern char *bcopy(), *bzero();
  1122. X  
  1123. X  #define ISALNUM(c) (isascii(c) && isalnum(c))
  1124. X--- 139,144 ----
  1125. X***************
  1126. X*** 380,387 ****
  1127. X     a constraint. */
  1128. X  typedef struct
  1129. X  {
  1130. X!   unsigned index:24,        /* Index into the parse array. */
  1131. X!        constraint:8;    /* Constraint for matching this position. */
  1132. X  } _position;
  1133. X  
  1134. X  /* Sets of positions are stored as arrays. */
  1135. X--- 377,384 ----
  1136. X     a constraint. */
  1137. X  typedef struct
  1138. X  {
  1139. X!   unsigned index;        /* Index into the parse array. */
  1140. X!   unsigned constraint;        /* Constraint for matching this position. */
  1141. X  } _position;
  1142. X  
  1143. X  /* Sets of positions are stored as arrays. */
  1144. X***************
  1145. X*** 398,407 ****
  1146. X  {
  1147. X    int hash;            /* Hash of the positions of this state. */
  1148. X    _position_set elems;        /* Positions this state could match. */
  1149. X!   unsigned newline:1,        /* True if previous state matched newline. */
  1150. X!        letter:1,        /* True if previous state matched a letter. */
  1151. X!        backref:1,        /* True if this state matches a \<digit>. */
  1152. X!        constraint:8;    /* Constraint for this state to accept. */
  1153. X    int first_end;        /* Token value of the first _END in elems. */
  1154. X  } _dfa_state;
  1155. X  
  1156. X--- 395,404 ----
  1157. X  {
  1158. X    int hash;            /* Hash of the positions of this state. */
  1159. X    _position_set elems;        /* Positions this state could match. */
  1160. X!   char newline;            /* True if previous state matched newline. */
  1161. X!   char letter;            /* True if previous state matched a letter. */
  1162. X!   char backref;            /* True if this state matches a \<digit>. */
  1163. X!   unsigned char constraint;    /* Constraint for this state to accept. */
  1164. X    int first_end;        /* Token value of the first _END in elems. */
  1165. X  } _dfa_state;
  1166. X  
  1167. Xdiff -rcN grep-1.2/getopt.c grep-1.3/getopt.c
  1168. X*** grep-1.2/getopt.c    Sun Dec 11 10:37:36 1988
  1169. X--- grep-1.3/getopt.c    Tue Feb 28 17:44:55 1989
  1170. X***************
  1171. X*** 406,412 ****
  1172. X          if (opterr != 0)
  1173. X            fprintf (stderr, "%s: no argument for `-%c' option\n",
  1174. X                 argv[0], c);
  1175. X!         optarg = 0;
  1176. X            }
  1177. X          else
  1178. X            /* We already incremented `optind' once;
  1179. X--- 406,412 ----
  1180. X          if (opterr != 0)
  1181. X            fprintf (stderr, "%s: no argument for `-%c' option\n",
  1182. X                 argv[0], c);
  1183. X!         c = '?';
  1184. X            }
  1185. X          else
  1186. X            /* We already incremented `optind' once;
  1187. Xdiff -rcN grep-1.2/grep.c grep-1.3/grep.c
  1188. X*** grep-1.2/grep.c    Tue Dec 13 10:54:54 1988
  1189. X--- grep-1.3/grep.c    Tue Feb 28 23:05:53 1989
  1190. X***************
  1191. X*** 368,376 ****
  1192. X        /* If a potential backreference is indicated, try it out with
  1193. X           a backtracking matcher to make sure the line is a match. */
  1194. X        if (try_backref && re_search(®ex, matching_line,
  1195. X!                        next_line - matching_line,
  1196. X                         0,
  1197. X!                        next_line - matching_line,
  1198. X                         NULL) < 0)
  1199. X          {
  1200. X            resume = next_line;
  1201. X--- 368,376 ----
  1202. X        /* If a potential backreference is indicated, try it out with
  1203. X           a backtracking matcher to make sure the line is a match. */
  1204. X        if (try_backref && re_search(®ex, matching_line,
  1205. X!                        next_line - matching_line - 1,
  1206. X                         0,
  1207. X!                        next_line - matching_line - 1,
  1208. X                         NULL) < 0)
  1209. X          {
  1210. X            resume = next_line;
  1211. X***************
  1212. X*** 542,548 ****
  1213. X    exit(ERROR);
  1214. X  }
  1215. X  
  1216. X! static char version[] = "GNU e?grep, version 1.2";
  1217. X  
  1218. X  main(argc, argv)
  1219. X       int argc;
  1220. X--- 542,548 ----
  1221. X    exit(ERROR);
  1222. X  }
  1223. X  
  1224. X! static char version[] = "GNU e?grep, version 1.3";
  1225. X  
  1226. X  main(argc, argv)
  1227. X       int argc;
  1228. X***************
  1229. X*** 679,695 ****
  1230. X      break;
  1231. X        }
  1232. X  
  1233. X!   /* Set the syntax depending on arg 0 and whether to ignore case. */
  1234. X!   if (*prog == 'e')
  1235. X!     {
  1236. X!       regsyntax(RE_SYNTAX_EGREP, ignore_case);
  1237. X!       re_set_syntax(RE_SYNTAX_EGREP);
  1238. X!     }
  1239. X!   else
  1240. X!     {
  1241. X!       regsyntax(RE_SYNTAX_GREP, ignore_case);
  1242. X!       re_set_syntax(RE_SYNTAX_GREP);
  1243. X!     }
  1244. X  
  1245. X    /* Compile the regexp according to all the options. */
  1246. X    if (regexp_file)
  1247. X--- 679,692 ----
  1248. X      break;
  1249. X        }
  1250. X  
  1251. X!   /* Set the syntax depending on whether we are EGREP or not. */
  1252. X! #ifdef EGREP
  1253. X!   regsyntax(RE_SYNTAX_EGREP, ignore_case);
  1254. X!   re_set_syntax(RE_SYNTAX_EGREP);
  1255. X! #else
  1256. X!   regsyntax(RE_SYNTAX_GREP, ignore_case);
  1257. X!   re_set_syntax(RE_SYNTAX_GREP);
  1258. X! #endif
  1259. X  
  1260. X    /* Compile the regexp according to all the options. */
  1261. X    if (regexp_file)
  1262. X***************
  1263. X*** 712,717 ****
  1264. X--- 709,715 ----
  1265. X        if (i == len)
  1266. X          the_regexp = realloc(the_regexp, len *= 2);
  1267. X      }
  1268. X+       fclose(fp);
  1269. X        /* Nuke the concluding newline so we won't match the empty string. */
  1270. X        if (i > 0 && the_regexp[i - 1] == '\n')
  1271. X      --i;
  1272. Xdiff -rcN grep-1.2/grep.man grep-1.3/grep.man
  1273. X*** grep-1.2/grep.man    Tue Dec 13 11:46:46 1988
  1274. X--- grep-1.3/grep.man    Tue Feb 28 21:42:46 1989
  1275. X***************
  1276. X*** 6,21 ****
  1277. X  .B grep
  1278. X  [
  1279. X  .B \-CVbchilnsvwx
  1280. X! ]
  1281. X! [
  1282. X! .B \-\c
  1283. X! .I num
  1284. X! ]
  1285. X! [
  1286. X  .B \-AB
  1287. X  .I num
  1288. X! ]
  1289. X! [ [
  1290. X  .B \-e
  1291. X  ]
  1292. X  .I expr
  1293. X--- 6,17 ----
  1294. X  .B grep
  1295. X  [
  1296. X  .B \-CVbchilnsvwx
  1297. X! ] [
  1298. X! .BI \- num
  1299. X! ] [
  1300. X  .B \-AB
  1301. X  .I num
  1302. X! ] [ [
  1303. X  .B \-e
  1304. X  ]
  1305. X  .I expr
  1306. X***************
  1307. X*** 254,260 ****
  1308. X  the aforementioned BMG search for a large class of regexps.
  1309. X  .PP
  1310. X  Richard Stallman wrote the backtracking regexp matcher that is
  1311. X! used for \\fIdigit\fP backreferences, as well as the getopt that
  1312. X  is provided for 4.2BSD sites.  The backtracking matcher was
  1313. X  originally written for GNU Emacs.
  1314. X  .PP
  1315. X--- 250,256 ----
  1316. X  the aforementioned BMG search for a large class of regexps.
  1317. X  .PP
  1318. X  Richard Stallman wrote the backtracking regexp matcher that is
  1319. X! used for \\\fIdigit\fP backreferences, as well as the getopt that
  1320. X  is provided for 4.2BSD sites.  The backtracking matcher was
  1321. X  originally written for GNU Emacs.
  1322. X  .PP
  1323. Xdiff -rcN grep-1.2/regex.c grep-1.3/regex.c
  1324. X*** grep-1.2/regex.c    Sun Oct 16 14:55:19 1988
  1325. X--- grep-1.3/regex.c    Tue Feb 28 17:44:59 1989
  1326. X***************
  1327. X*** 1,106 ****
  1328. X! /* Extended regular expression matching and search.
  1329. X!    Copyright (C) 1985 Free Software Foundation, Inc.
  1330. X  
  1331. X!                NO WARRANTY
  1332. X  
  1333. X-   BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
  1334. X- NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW.  EXCEPT
  1335. X- WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,
  1336. X- RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS"
  1337. X- WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
  1338. X- BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  1339. X- FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY
  1340. X- AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE PROGRAM PROVE
  1341. X- DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
  1342. X- CORRECTION.
  1343. X  
  1344. X!  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
  1345. X! STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY
  1346. X! WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE
  1347. X! LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR
  1348. X! OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
  1349. X! USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR
  1350. X! DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR
  1351. X! A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS
  1352. X! PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
  1353. X! DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
  1354. X! 
  1355. X!         GENERAL PUBLIC LICENSE TO COPY
  1356. X! 
  1357. X!   1. You may copy and distribute verbatim copies of this source file
  1358. X! as you receive it, in any medium, provided that you conspicuously and
  1359. X! appropriately publish on each copy a valid copyright notice "Copyright
  1360. X! (C) 1985 Free Software Foundation, Inc."; and include following the
  1361. X! copyright notice a verbatim copy of the above disclaimer of warranty
  1362. X! and of this License.  You may charge a distribution fee for the
  1363. X! physical act of transferring a copy.
  1364. X! 
  1365. X!   2. You may modify your copy or copies of this source file or
  1366. X! any portion of it, and copy and distribute such modifications under
  1367. X! the terms of Paragraph 1 above, provided that you also do the following:
  1368. X! 
  1369. X!     a) cause the modified files to carry prominent notices stating
  1370. X!     that you changed the files and the date of any change; and
  1371. X! 
  1372. X!     b) cause the whole of any work that you distribute or publish,
  1373. X!     that in whole or in part contains or is a derivative of this
  1374. X!     program or any part thereof, to be licensed at no charge to all
  1375. X!     third parties on terms identical to those contained in this
  1376. X!     License Agreement (except that you may choose to grant more extensive
  1377. X!     warranty protection to some or all third parties, at your option).
  1378. X! 
  1379. X!     c) You may charge a distribution fee for the physical act of
  1380. X!     transferring a copy, and you may at your option offer warranty
  1381. X!     protection in exchange for a fee.
  1382. X! 
  1383. X! Mere aggregation of another unrelated program with this program (or its
  1384. X! derivative) on a volume of a storage or distribution medium does not bring
  1385. X! the other program under the scope of these terms.
  1386. X! 
  1387. X!   3. You may copy and distribute this program (or a portion or derivative
  1388. X! of it, under Paragraph 2) in object code or executable form under the terms
  1389. X! of Paragraphs 1 and 2 above provided that you also do one of the following:
  1390. X! 
  1391. X!     a) accompany it with the complete corresponding machine-readable
  1392. X!     source code, which must be distributed under the terms of
  1393. X!     Paragraphs 1 and 2 above; or,
  1394. X! 
  1395. X!     b) accompany it with a written offer, valid for at least three
  1396. X!     years, to give any third party free (except for a nominal
  1397. X!     shipping charge) a complete machine-readable copy of the
  1398. X!     corresponding source code, to be distributed under the terms of
  1399. X!     Paragraphs 1 and 2 above; or,
  1400. X! 
  1401. X!     c) accompany it with the information you received as to where the
  1402. X!     corresponding source code may be obtained.  (This alternative is
  1403. X!     allowed only for noncommercial distribution and only if you
  1404. X!     received the program in object code or executable form alone.)
  1405. X! 
  1406. X! For an executable file, complete source code means all the source code for
  1407. X! all modules it contains; but, as a special exception, it need not include
  1408. X! source code for modules which are standard libraries that accompany the
  1409. X! operating system on which the executable file runs.
  1410. X! 
  1411. X!   4. You may not copy, sublicense, distribute or transfer this program
  1412. X! except as expressly provided under this License Agreement.  Any attempt
  1413. X! otherwise to copy, sublicense, distribute or transfer this program is void and
  1414. X! your rights to use the program under this License agreement shall be
  1415. X! automatically terminated.  However, parties who have received computer
  1416. X! software programs from you with this License Agreement will not have
  1417. X! their licenses terminated so long as such parties remain in full compliance.
  1418. X! 
  1419. X!   5. If you wish to incorporate parts of this program into other free
  1420. X! programs whose distribution conditions are different, write to the Free
  1421. X! Software Foundation at 675 Mass Ave, Cambridge, MA 02139.  We have not yet
  1422. X! worked out a simple rule that can be stated here, but we will often permit
  1423. X! this.  We will be guided by the two goals of preserving the free status of
  1424. X! all derivatives of our free software and of promoting the sharing and reuse of
  1425. X! software.
  1426. X! 
  1427. X! 
  1428. X! In other words, you are welcome to use, share and improve this program.
  1429. X! You are forbidden to forbid anyone else to use, share and improve
  1430. X! what you give them.   Help stamp out software-hoarding!  */
  1431. X  
  1432. X  
  1433. X  /* To test, compile with -Dtest.
  1434. X--- 1,24 ----
  1435. X! /* Extended regular expression matching and search library.
  1436. X!    Copyright (C) 1985, 1989 Free Software Foundation, Inc.
  1437. X  
  1438. X!    This program is free software; you can redistribute it and/or modify
  1439. X!    it under the terms of the GNU General Public License as published by
  1440. X!    the Free Software Foundation; either version 1, or (at your option)
  1441. X!    any later version.
  1442. X! 
  1443. X!    This program is distributed in the hope that it will be useful,
  1444. X!    but WITHOUT ANY WARRANTY; without even the implied warranty of
  1445. X!    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1446. X!    GNU General Public License for more details.
  1447. X! 
  1448. X!    You should have received a copy of the GNU General Public License
  1449. X!    along with this program; if not, write to the Free Software
  1450. X!    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1451. X  
  1452. X  
  1453. X!    In other words, you are welcome to use, share and improve this program.
  1454. X!    You are forbidden to forbid anyone else to use, share and improve
  1455. X!    what you give them.   Help stamp out software-hoarding!  */
  1456. X  
  1457. X  
  1458. X  /* To test, compile with -Dtest.
  1459. Xdiff -rcN grep-1.2/regex.h grep-1.3/regex.h
  1460. X*** grep-1.2/regex.h    Sat Aug 13 13:15:10 1988
  1461. X--- grep-1.3/regex.h    Tue Feb 28 17:44:59 1989
  1462. X***************
  1463. X*** 1,106 ****
  1464. X  /* Definitions for data structures callers pass the regex library.
  1465. X!    Copyright (C) 1985 Free Software Foundation, Inc.
  1466. X  
  1467. X!                NO WARRANTY
  1468. X  
  1469. X-   BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
  1470. X- NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW.  EXCEPT
  1471. X- WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,
  1472. X- RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS"
  1473. X- WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
  1474. X- BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  1475. X- FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY
  1476. X- AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE PROGRAM PROVE
  1477. X- DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
  1478. X- CORRECTION.
  1479. X  
  1480. X!  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
  1481. X! STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY
  1482. X! WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE
  1483. X! LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR
  1484. X! OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
  1485. X! USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR
  1486. X! DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR
  1487. X! A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS
  1488. X! PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
  1489. X! DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
  1490. X! 
  1491. X!         GENERAL PUBLIC LICENSE TO COPY
  1492. X! 
  1493. X!   1. You may copy and distribute verbatim copies of this source file
  1494. X! as you receive it, in any medium, provided that you conspicuously and
  1495. X! appropriately publish on each copy a valid copyright notice "Copyright
  1496. X! (C) 1985 Free Software Foundation, Inc."; and include following the
  1497. X! copyright notice a verbatim copy of the above disclaimer of warranty
  1498. X! and of this License.  You may charge a distribution fee for the
  1499. X! physical act of transferring a copy.
  1500. X! 
  1501. X!   2. You may modify your copy or copies of this source file or
  1502. X! any portion of it, and copy and distribute such modifications under
  1503. X! the terms of Paragraph 1 above, provided that you also do the following:
  1504. X! 
  1505. X!     a) cause the modified files to carry prominent notices stating
  1506. X!     that you changed the files and the date of any change; and
  1507. X! 
  1508. X!     b) cause the whole of any work that you distribute or publish,
  1509. X!     that in whole or in part contains or is a derivative of this
  1510. X!     program or any part thereof, to be licensed at no charge to all
  1511. X!     third parties on terms identical to those contained in this
  1512. X!     License Agreement (except that you may choose to grant more extensive
  1513. X!     warranty protection to some or all third parties, at your option).
  1514. X! 
  1515. X!     c) You may charge a distribution fee for the physical act of
  1516. X!     transferring a copy, and you may at your option offer warranty
  1517. X!     protection in exchange for a fee.
  1518. X! 
  1519. X! Mere aggregation of another unrelated program with this program (or its
  1520. X! derivative) on a volume of a storage or distribution medium does not bring
  1521. X! the other program under the scope of these terms.
  1522. X! 
  1523. X!   3. You may copy and distribute this program (or a portion or derivative
  1524. X! of it, under Paragraph 2) in object code or executable form under the terms
  1525. X! of Paragraphs 1 and 2 above provided that you also do one of the following:
  1526. X! 
  1527. X!     a) accompany it with the complete corresponding machine-readable
  1528. X!     source code, which must be distributed under the terms of
  1529. X!     Paragraphs 1 and 2 above; or,
  1530. X! 
  1531. X!     b) accompany it with a written offer, valid for at least three
  1532. X!     years, to give any third party free (except for a nominal
  1533. X!     shipping charge) a complete machine-readable copy of the
  1534. X!     corresponding source code, to be distributed under the terms of
  1535. X!     Paragraphs 1 and 2 above; or,
  1536. X! 
  1537. X!     c) accompany it with the information you received as to where the
  1538. X!     corresponding source code may be obtained.  (This alternative is
  1539. X!     allowed only for noncommercial distribution and only if you
  1540. X!     received the program in object code or executable form alone.)
  1541. X! 
  1542. X! For an executable file, complete source code means all the source code for
  1543. X! all modules it contains; but, as a special exception, it need not include
  1544. X! source code for modules which are standard libraries that accompany the
  1545. X! operating system on which the executable file runs.
  1546. X! 
  1547. X!   4. You may not copy, sublicense, distribute or transfer this program
  1548. X! except as expressly provided under this License Agreement.  Any attempt
  1549. X! otherwise to copy, sublicense, distribute or transfer this program is void and
  1550. X! your rights to use the program under this License agreement shall be
  1551. X! automatically terminated.  However, parties who have received computer
  1552. X! software programs from you with this License Agreement will not have
  1553. X! their licenses terminated so long as such parties remain in full compliance.
  1554. X! 
  1555. X!   5. If you wish to incorporate parts of this program into other free
  1556. X! programs whose distribution conditions are different, write to the Free
  1557. X! Software Foundation at 675 Mass Ave, Cambridge, MA 02139.  We have not yet
  1558. X! worked out a simple rule that can be stated here, but we will often permit
  1559. X! this.  We will be guided by the two goals of preserving the free status of
  1560. X! all derivatives of our free software and of promoting the sharing and reuse of
  1561. X! software.
  1562. X! 
  1563. X! 
  1564. X! In other words, you are welcome to use, share and improve this program.
  1565. X! You are forbidden to forbid anyone else to use, share and improve
  1566. X! what you give them.   Help stamp out software-hoarding!  */
  1567. X  
  1568. X  
  1569. X  /* Define number of parens for which we record the beginnings and ends.
  1570. X--- 1,24 ----
  1571. X  /* Definitions for data structures callers pass the regex library.
  1572. X!    Copyright (C) 1985, 1989 Free Software Foundation, Inc.
  1573. X  
  1574. X!    This program is free software; you can redistribute it and/or modify
  1575. X!    it under the terms of the GNU General Public License as published by
  1576. X!    the Free Software Foundation; either version 1, or (at your option)
  1577. X!    any later version.
  1578. X! 
  1579. X!    This program is distributed in the hope that it will be useful,
  1580. X!    but WITHOUT ANY WARRANTY; without even the implied warranty of
  1581. X!    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1582. X!    GNU General Public License for more details.
  1583. X! 
  1584. X!    You should have received a copy of the GNU General Public License
  1585. X!    along with this program; if not, write to the Free Software
  1586. X!    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1587. X  
  1588. X  
  1589. X!    In other words, you are welcome to use, share and improve this program.
  1590. X!    You are forbidden to forbid anyone else to use, share and improve
  1591. X!    what you give them.   Help stamp out software-hoarding!  */
  1592. X  
  1593. X  
  1594. X  /* Define number of parens for which we record the beginnings and ends.
  1595. X
  1596. END_OF_FILE
  1597. if test 46818 -ne `wc -c <'cvt1.2to1.3'`; then
  1598.     echo shar: \"'cvt1.2to1.3'\" unpacked with wrong size!
  1599. fi
  1600. # end of 'cvt1.2to1.3'
  1601. fi
  1602. echo shar: End of shell archive.
  1603. exit 0
  1604.